const fs = require('fs').promises;
const path = require('path');
const cron = require('node-cron');

class TaskService {
    constructor() {
        this.dataFile = path.join(__dirname, './data/task.json');
        this.ensureDataFile();
        this.taskInstances = {}; // 用于存储 cronJob 实例
        // this.loadAllTasksAndSchedule();
    }

    async loadAllTasksAndSchedule(taskHandler) {
        const tasks = await this.selectAllTask();

        for (const task of tasks) {
            if (!task.enabled) continue;

            const cronExpression = this.parseTimeToCron(task.taskTime);
            console.log(`创建定时任务：${task.taskName}, 时间：${task.taskTime}, cron表达式：${cronExpression}`);

            const cronJob = cron.schedule(cronExpression, () => {
                console.log(`执行任务：${task.taskName} - ${new Date().toLocaleString()}`);
                taskHandler(task);
            }, {
                scheduled: false,
                timezone: 'Asia/Shanghai' // 设置时区为中国时区
            });

            if (task.enabled) {
                cronJob.start();
                console.log(`任务已启动：${task.taskName}`);
            }

            this.taskInstances[task.id] = cronJob;
        }
        console.log('已加载所有任务并调度', Object.keys(this.taskInstances));
    }

    async startTaskById(id,handler) {
        try {
            const tasks = await this.selectAllTask();
            const task = tasks.find(t => t.id === id);

            if (!task) throw new Error(`任务不存在`);

            const cronJob = this.taskInstances[id];
            if (cronJob) {
                cronJob.start();
            } else {
                // 重新创建定时任务
                const cronExpression = this.parseTimeToCron(task.taskTime);
                const newJob = cron.schedule(cronExpression, () => {
                    console.log(`执行任务：${task.taskName} - ${new Date().toLocaleString()}`);
                    handler(task);
                }, {
                    timezone: 'Asia/Shanghai'
                });
                this.taskInstances[id] = newJob;
            }

            task.enabled = true;
            await fs.writeFile(this.dataFile, JSON.stringify(
                tasks.map(t => t.id === id ? task : t),
                null,
                2
            ));

            return true;
        } catch (error) {
            console.error('启动任务失败:', error);
            return false;
        }
    }

    async stopTaskById(id) {
        try {
            const tasks = await this.selectAllTask();
            const task = tasks.find(t => t.id === id);

            if (!task) throw new Error(`任务不存在`);

            const cronJob = this.taskInstances[id];
            if (cronJob) {
                cronJob.stop();
            }

            task.enabled = false;
            await fs.writeFile(this.dataFile, JSON.stringify(
                tasks.map(t => t.id === id ? task : t),
                null,
                2
            ));

            return true;
        } catch (error) {
            console.error('停止任务失败:', error);
            return false;
        }
    }

    /** 确保数据文件存在*/
    async ensureDataFile() {
        try {
            await fs.access(this.dataFile);
        } catch {
            // 如果文件不存在，创建空的数据文件
            await fs.mkdir(path.dirname(this.dataFile), { recursive: true });
            await fs.writeFile(this.dataFile, JSON.stringify([]));
        }
    }

    /** 读取所有 任务 */
    async selectAllTask() {
        try {
            const data = await fs.readFile(this.dataFile, 'utf8');
            return JSON.parse(data);
        } catch (error) {
            console.error('读取 Task 失败:', error);
            return error;
        }
    }

    /** 读取某个task */
    async selectUserTaskById(id) {
        try {
            const data = await fs.readFile(this.dataFile, 'utf8');
            return JSON.parse(data).find(o => o.id === id);
        } catch (error) {
            console.error('读取失败:', error);
            return error;
        }
    }

    generateUUID() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            const r = (Math.random() * 16) | 0;
            const v = c === 'x' ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        });
    }
    /**
     * 新增或更新任务（仅当任务处于关闭状态时才允许更新）
     *
     * @param {Object} param - 任务对象，包含 id（可选）
     * @returns {Promise<string|boolean>} 成功返回提示信息，失败返回错误
     */
    async addOrUpDateTask(param,handler) {

        try {
            const tasks = await this.selectAllTask();
            let message = '';

            if (param?.id) {
                // 更新任务逻辑
                const existingTask = tasks.find(t => t.id === param.id);

                if (!existingTask) {
                    return '任务不存在，无法更新';
                }

                // 仅允许在任务关闭的情况下更新
                if (existingTask.enabled === true) {
                    return '任务正在运行中，不能修改，请先关闭任务再操作';
                }

                // 停止旧的定时任务实例（如果存在）
                if (this.taskInstances[param.id]) {
                    this.taskInstances[param.id].stop();
                    delete this.taskInstances[param.id];
                }

                // 构建新任务数据（保留 enabled 状态）
                param.enabled = existingTask.enabled;
                const index = tasks.findIndex(t => t.id === param.id);
                tasks[index] = param;
                message = '任务更新成功';

                // 创建新的定时任务实例（未启动）
                const cronExpression = this.parseTimeToCron(param.taskTime);
                console.log('cronExpression:', cronExpression);

                const newJob = cron.schedule(cronExpression, () => {
                    console.log(`执行任务：${param.taskName} - ${new Date().toLocaleString()}`);
                    handler(existingTask);
                }, {
                    scheduled: false,
                    timezone: 'Asia/Shanghai'
                });

                console.log('newJob:', newJob);
                this.taskInstances[param.id] = newJob;

            } else {
                // 新增任务逻辑
                const newTask = {
                    ...param,
                    id: this.generateUUID(),
                    enabled: false // 默认关闭
                };

                // 创建定时任务实例（未启动）
                const cronExpression = this.parseTimeToCron(newTask.taskTime);
                console.log(`cronExpression${cronExpression}`);
                const newJob = cron.schedule(cronExpression, () => {
                    console.log(`执行任务：${newTask.taskName} - ${new Date().toLocaleString()}`);
                    handler(newTask);
                }, {
                    scheduled: false,
                    timezone: 'Asia/Shanghai'
                });

                this.taskInstances[newTask.id] = newJob;
                tasks.push(newTask);
                message = '任务创建成功';
            }

            // 保存更新后的任务列表
            await fs.writeFile(this.dataFile, JSON.stringify(tasks, null, 2));

            return message;
        } catch (error) {
            console.error('操作任务失败:', error);
            return '操作失败，请重试';
        }
    }

    /**
     * 将 'HH:mm:ss' 转换为 cron 表达式（秒 分 时 日 月 周几）
     * 修改为每天执行，确保任务每天都会生效
     */
    parseTimeToCron(timeStr) {
        const [hour, minute, second] = timeStr.split(':').map(Number);
        // 格式：秒 分 时 日 月 周几
        // * * * 表示每天、每月、每周都执行
        return `${second} ${minute} ${hour} * * *`;
    }

    /**  删除任务 */
    async deleteTaskById(id) {
        try {
            const tasks = await this.selectAllTask();
            const task = tasks.find(t => t.id === id);

            if (!task) throw new Error(`任务不存在`);

            const cronJob = this.taskInstances[id];
            if (cronJob) {
                cronJob.stop();
                delete this.taskInstances[id];
            }

            const updatedTasks = tasks.filter(t => t.id !== id);
            await fs.writeFile(this.dataFile, JSON.stringify(updatedTasks, null, 2));

            return true;
        } catch (error) {
            console.error('删除任务失败:', error);
            return false;
        }
    }

    /** 获取任务状态信息 */
    getTaskStatus() {
        const status = {};
        for (const [id, cronJob] of Object.entries(this.taskInstances)) {
            status[id] = {
                running: cronJob.running,
                nextDate: cronJob.nextDate ? cronJob.nextDate.toLocaleString() : '未设置'
            };
        }
        return status;
    }

    /** 重新加载所有任务 */
    async reloadAllTasks(taskHandler) {
        // 停止所有现有任务
        for (const [id, cronJob] of Object.entries(this.taskInstances)) {
            cronJob.stop();
        }
        this.taskInstances = {};

        // 重新加载任务
        await this.loadAllTasksAndSchedule(taskHandler);
        console.log('所有任务已重新加载');
    }
}

module.exports = TaskService;